function Mine(row, col, mine_count) {
    this.row = row
    this.col = col
    this.mine_count = mine_count
    this.squares = []   // 通过行列找出方块信息(类型，坐标，值)
    this.tds = []   // 通过行列找到单元格 dom
    this.surplus_mine = mine_count
    this.parent = document.getElementsByClassName('game-box')[0]
}

Mine.prototype.init = function () {
    var mine_list = this.random(),
        n = 0
    for (var row = 0; row < this.row; row++) {
        this.squares[row] = []
        for (var col = 0; col < this.col; col++) {
            if (mine_list.indexOf(n++) == -1) {
                this.squares[row][col] = {
                    type: 'number',
                    x: col,
                    y: row,
                    value: 0
                }
            } else {
                this.squares[row][col] = {
                    type: 'mine',
                    x: col,
                    y: row
                }
            }
        }
    }
    this.update_num()
    this.create()
    document.oncontextmenu = function (event) {
        event.preventDefault()
    }
    var mine_count = document.getElementsByClassName('mine-count')[0]
    mine_count.innerText = this.surplus_mine
}

Mine.prototype.random = function () {
    var square = new Array(this.row * this.col)
    for (var i = 0; i < square.length; i++) {
        square[i] = i
    }
    square.sort(function () { return 0.5 - Math.random() })
    return square.slice(0, this.mine_count)
}

Mine.prototype.create = function () {
    var table = document.createElement('table'),
        self = this;
    for (var row = 0; row < this.row; row++) {
        var tr = document.createElement('tr')
        this.tds[row] = []
        for (var col = 0; col < this.col; col++) {
            var td = document.createElement('td')
            this.tds[row][col] = td
            td.pos = [row, col] // dom 上存放行列位置信息
            td.onmousedown = function (event) {
                self.play(event, this)
            }
            tr.appendChild(td)
        }
        table.appendChild(tr)
    }
    this.parent.innerHTML = '' // 避免多次点击创建多个
    this.parent.appendChild(table)
}

// 获取周围方块的坐标
Mine.prototype.get_around = function (square) {
    var col = square.x,
        row = square.y,
        result = [];
    for (var x = col - 1; x < col + 2; x++) {
        for (var y = row - 1; y < row + 2; y++) {
            if (x < 0 ||
                y < 0 ||
                x > this.col - 1 ||
                y > this.row - 1 ||
                (x == col && y == row) ||
                this.squares[y][x].type == 'mine'
            )
                continue
            result.push([x, y])
        }  // 返回的是坐标
    }
    return result
}

Mine.prototype.update_num = function () {
    for (var row = 0; row < this.row; row++) {
        for (var col = 0; col < this.col; col++) {
            if (this.squares[row][col].type == 'mine') {
                var around = this.get_around(this.squares[row][col])
                len = around.length
                for (var k = 0; k < len; k++) {
                    this.squares[around[k][1]][around[k][0]].value++
                }
            }
        }
    }
}

Mine.prototype.play = function (event, obj) {
    var self = this,
        square = this.squares[obj.pos[0]][obj.pos[1]],
        class_list = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight']

    function spread(square) {  // 扩散算法
        var around = self.get_around(square)
        for (var i = 0; i < around.length; i++) {
            var row = around[i][1],
                col = around[i][0],
                class_name = class_list[self.squares[row][col].value - 1]
            self.tds[row][col].classList.add('clicked', class_name)
            // 扩散时将已经插的旗重置回去
            if (self.tds[row][col].classList.contains('flag')) {
                self.tds[row][col].classList.remove('flag')
                self.surplus_mine++
            }
            if (!self.squares[row][col].value) {
                if (!self.tds[row][col].is_clicked) {
                    self.tds[row][col].is_clicked = true
                    spread(self.squares[row][col])
                }
            } else {
                self.tds[row][col].innerText = self.squares[row][col].value
            }
        }
    }
    if (event.which == 1 && obj.className != 'flag') {
        if (square.type == 'mine') {
            this.game_over(obj)
        } else {
            obj.classList.add('clicked')
            if (square.value) {
                obj.innerText = square.value
                obj.classList.add(class_list[square.value - 1])
            } else {
                spread(square)
                var mine_count = document.getElementsByClassName('mine-count')[0]
                mine_count.innerText = this.surplus_mine
            }
        }
    } else if (event.which == 3) {
        if (!obj.classList.contains('clicked')) {
            if (obj.classList.contains('flag')) {
                obj.className = ''
                this.surplus_mine++
            } else {
                if (this.surplus_mine > 0) {
                    obj.className = 'flag'
                    this.surplus_mine--
                }
            }
            if (this.surplus_mine == 0)
                this.victory()
            var mine_count = document.getElementsByClassName('mine-count')[0]
            mine_count.innerText = this.surplus_mine
        }
    }
}

Mine.prototype.game_over = function (click_obj) {
    for (var row = 0; row < this.row; row++) {
        for (var col = 0; col < this.col; col++) {
            var square = this.squares[row][col]
            if (square.type == 'mine') {
                this.tds[row][col].className = 'mine'
            }
            this.tds[row][col].onmousedown = null
        }
    }
    click_obj.style.backgroundColor = 'red'
    alert('你被炸死了！')
}

Mine.prototype.victory = function () {
    var is_victory = true,
        flag = document.getElementsByClassName('flag')
    for (var i = 0; i < this.mine_count; i++) {
        var row = flag[i].pos[0],
            col = flag[i].pos[1]
        if (this.squares[row][col].type != 'mine') {
            is_victory = false
            break
        }
    }
    if (is_victory)
        alert('恭喜你，游戏胜利！')
}

var mine,
    buttons = document.getElementsByTagName('button'),
    ln = 0,	//用来处理当前选中的状态
    arr = [[9, 9, 10], [16, 16, 40], [28, 28, 99]];	//不同级别的行数列数雷数

for (let i = 0; i < 3; i++) {
    buttons[i].onclick = function () {
        buttons[ln].className = '';
        this.className = 'active';
        mine = new Mine(...arr[i]);
        mine.init();
        ln = i;
    }
}

buttons[0].click()
buttons[3].onclick = function () {
    var active = document.getElementsByClassName('active')[0]
    active.click()
}
